#!/usr/bin/env python
# -*- coding:utf-8 -*-
# 布控预警订阅处理C++接口
# 作者：王成
# 日期：2017-04-10
import os,datetime,time
import json
import re
import threading
import logging

class HANDLE(object):
    class CHECK_ITEM():
        LICENSE_PLATE = 1
        LP_COLOR_ID = 2
        BRAND_ID = 3
        MODEL_ID = 4
        YEAR_ID = 5
        LEVEL_ID = 6
        LOCATION_ID = 7
        DEVICE_ID = 8
        DIRECTION_ID = 9
        SOURCE_ID = 10

    class Task():
        def __init__(self,task_id=0,valid_period_b=0,valid_period_e=0,handle_b=0,handle_e=0,license_plates_a=set(),license_plates_b=[],lp_color_ids=set(),brand_ids=set(),model_ids=set(),year_ids=set(),level_ids=set(),location_ids=set(),direction_ids=set(),device_ids=set(),source_id=0,check_items=[]):
            self.task_id = task_id#任务ID
            self.valid_period_b = valid_period_b#有效期开始时间
            self.valid_period_e = valid_period_e#有效期截至时间
            self.handle_b = handle_b#每天的布控开始时间[0-86400]
            self.handle_e = handle_e#每天的布控结束时间[0-86400]
            self.license_plates_a = license_plates_a#车牌精确车牌
            self.license_plates_b = license_plates_b#车牌模糊车牌
            self.lp_color_ids = lp_color_ids#车牌颜色
            self.brand_ids = brand_ids#品牌
            self.model_ids = model_ids#型号
            self.year_ids = year_ids#年款
            self.level_ids = level_ids#类型
            self.location_ids = location_ids#卡口
            self.direction_ids = direction_ids#方向
            self.device_ids = device_ids#设备
            self.source_id = source_id#来源[1卡口，2电警]
            self.check_items = check_items#检测项
            
    def __init__(self):
        self.tasks = []
        self.tasks_add = set()
        self.date_0 = 0
        t = threading.Thread(target=self.update)
        t.setDaemon(True)
        t.start()
        
    def update(self):
        while 1:
            d = datetime.datetime.now().date()
            self.date_0 = time.mktime((d.year,d.month,d.day,0,0,0,0,0,0))
            #print self.date_0
            time.sleep(10)
            
    def is_in_set(self,sets,item):
        if item in sets:
            return True
        else:
            return False
            
    def is_equal(self,item1,item2):
        if item1 is item2:
            return True
        else:
            return False

    def process(self,license_plates=[],lp_color_id=0,capture_time=0,brand_id=0,model_id=0,year_id=0,level_id=0,location_id=0,direction_id=0,source_id=0,device_id=0):
        #print 'tasks_add2',len(self.tasks_add)
        result = {}
        c_handle_time = capture_time - self.date_0
        license_plates_u = []
        for lp in license_plates:
            license_plates_u.append(lp.decode('utf8'))
        #license_plate_u = license_plate.decode('utf8')
        for task in self.tasks:
            task_id = task.task_id
            match_task_id = 0
            match_lp_id = 0
            if task.handle_b <= c_handle_time<=task.handle_e and task.valid_period_b <= capture_time <= task.valid_period_e:
                match_task_id = task_id
                for ci in task.check_items:
                    if ci is self.CHECK_ITEM.SOURCE_ID:
                        #print 'CHECK_ITEM.SOURCE_ID'
                        if self.is_equal(task.source_id,source_id) is False:
                            match_task_id = 0
                            break
                    elif ci is self.CHECK_ITEM.LICENSE_PLATE:
                        #print 'CHECK_ITEM.LICENSE_PLATE'
                        if license_plates_u[0] in task.license_plates_a:
                            match_lp_id = 1
                            continue
                        if license_plates_u[1] in task.license_plates_a:
                            match_lp_id = 2
                            continue
                        is_get = 0
                        for compiled_pattern in task.license_plates_b:
                            if compiled_pattern.match(license_plates_u[0]):
                                is_get = 1
                                match_lp_id = 1
                                break
                        if is_get==0 and license_plates_u[0] is not license_plates_u[1]:
                            for compiled_pattern in task.license_plates_b:
                                if compiled_pattern.match(license_plates_u[1]):
                                    is_get = 1
                                    match_lp_id = 2
                                    break
                        if is_get is 0:
                            match_task_id = 0
                            break
                    elif ci is self.CHECK_ITEM.LEVEL_ID:
                        #print 'CHECK_ITEM.LEVEL_ID'
                        if self.is_in_set(task.level_ids,level_id) is False:
                            match_task_id = 0
                            break
                    elif ci is self.CHECK_ITEM.YEAR_ID:
                        #print 'CHECK_ITEM.YEAR_ID'
                        if self.is_in_set(task.year_ids,year_id) is False:
                            match_task_id = 0
                            break
                    elif ci is self.CHECK_ITEM.MODEL_ID:
                        #print 'CHECK_ITEM.MODEL_ID'
                        if self.is_in_set(task.model_ids,model_id) is False:
                            match_task_id = 0
                            break
                    elif ci is self.CHECK_ITEM.BRAND_ID:
                        #print 'CHECK_ITEM.BRAND_ID'
                        if self.is_in_set(task.brand_ids,brand_id) is False:
                            match_task_id = 0
                            break
                    elif ci is self.CHECK_ITEM.LP_COLOR_ID:
                        #print 'CHECK_ITEM.LP_COLOR_ID'
                        if self.is_in_set(task.lp_color_ids,lp_color_id) is False:
                            match_task_id = 0
                            break
                    elif ci is self.CHECK_ITEM.LOCATION_ID:
                        #print 'CHECK_ITEM.LOCATION_ID'
                        if self.is_in_set(task.location_ids,location_id) is False:
                            match_task_id = 0
                            break
                    elif ci is self.CHECK_ITEM.DIRECTION_ID:
                        #print 'CHECK_ITEM.DIRECTION_ID'
                        if self.is_in_set(task.direction_ids,direction_id) is False:
                            match_task_id = 0
                            break
                    elif ci is self.CHECK_ITEM.DEVICE_ID:
                        #print 'CHECK_ITEM.DEVICE_ID'
                        if self.is_in_set(task.device_ids,device_id) is False:
                            match_task_id = 0
                            break
            
            if match_task_id is 0:
                continue
            else:
                result[match_task_id] = match_lp_id
        return result
        
    def add_task(self,task_id,task_info):
        #print task_info
        if task_id not in self.tasks_add:
            json_r = json.loads(task_info)
            check_items = []
            if not json_r['valid_period_b'] or not json_r['valid_period_e']:
                logging.info('错误的有效期[%d]', int(task['task_id']))
                return False
            if not json_r['handle_e']:
                logging.info('错误的布控截至时段[%d],handle_e:%s',int(task['task_id']),json_r['handle_e'])
                return False
            valid_period_b = int(json_r['valid_period_b'])
            valid_period_e = int(json_r['valid_period_e'])
            handle_b = int(json_r['handle_b'])
            handle_e = int(json_r['handle_e'])
            license_plates_a = set()#精确车牌
            license_plates_b = []#模糊车牌
            lp_color_ids = set()
            brand_ids = set()
            model_ids = set()
            year_ids = set()
            level_ids = set()
            location_ids = set()
            direction_ids = set()
            device_ids = set()
            source_id = 0
            if 'lp_color_ids' in json_r and json_r['lp_color_ids']:
                for lp_color_id in json_r['lp_color_ids']:
                    if int(lp_color_id)>0:
                        lp_color_ids.add(int(lp_color_id))
                if len(lp_color_ids)>0:
                    check_items.append(self.CHECK_ITEM.LP_COLOR_ID)
            if 'brand_ids' in json_r and json_r['brand_ids']:
                for brand_id in json_r['brand_ids']:
                    if int(brand_id)>0:
                        brand_ids.add(int(brand_id))
                if len(brand_ids)>0:
                    check_items.append(self.CHECK_ITEM.BRAND_ID)
            if 'model_ids' in json_r and json_r['model_ids']:
                for model_id in json_r['model_ids']:
                    if int(model_id)>0:
                        model_ids.add(int(model_id))
                if len(model_ids)>0:
                    check_items.append(self.CHECK_ITEM.MODEL_ID)
            if 'year_ids' in json_r and json_r['year_ids']:
                for year_id in json_r['year_ids']:
                    if int(year_id)>0:
                        year_ids.add(int(year_id))
                if len(year_ids)>0:
                    check_items.append(self.CHECK_ITEM.YEAR_ID)
            if 'level_ids' in json_r and json_r['level_ids']:
                for level_id in json_r['level_ids']:
                    if int(level_id)>0:
                        level_ids.add(int(level_id))
                if len(level_ids)>0:
                    check_items.append(self.CHECK_ITEM.LEVEL_ID)
            if 'location_ids' in json_r and json_r['location_ids']:
                check_items.append(self.CHECK_ITEM.LOCATION_ID)
                for location_id in json_r['location_ids']:
                    location_ids.add(location_id)
            if 'direction_ids' in json_r and json_r['direction_ids']:
                check_items.append(self.CHECK_ITEM.DIRECTION_ID)
                for direction_id in json_r['direction_ids']:
                    direction_ids.add(direction_id)
            if 'device_ids' in json_r and json_r['device_ids']:
                check_items.append(self.CHECK_ITEM.DEVICE_ID)
                for device_id in json_r['device_ids']:
                    device_ids.add(device_id)
            if 'license_plates' in json_r and json_r['license_plates']:
                check_items.append(self.CHECK_ITEM.LICENSE_PLATE)
                for lp in json_r['license_plates']:
                    if '?' in lp or '*' in lp:
                        if lp.startswith('?'):
                            lp = "[\u4e00-\u9fa5]"+lp[1:]
                        else:
                            if isinstance(lp, unicode):
                                pass
                            else:
                                lp = lp.decode('utf8')
                        lp = '[\w]*'+lp.replace('?','[\w]').replace('*','[\w]*')+'[\w]*'
                        lp = eval("ur'%s'" % lp)
                        #print lp,"\n"
                        license_plates_b.append(re.compile(lp)   )
                    else:
                        license_plates_a.add(lp)
            if 'source_id' in json_r and json_r['source_id']:
                check_items.append(self.CHECK_ITEM.SOURCE_ID)
                source_id = int(json_r['source_id'])
            if check_items:
                task = self.Task(task_id,valid_period_b=valid_period_b,valid_period_e=valid_period_e,handle_b=handle_b,handle_e=handle_e,license_plates_a=license_plates_a,license_plates_b=license_plates_b,lp_color_ids=lp_color_ids,brand_ids=brand_ids,model_ids=model_ids,year_ids=year_ids,level_ids=level_ids,location_ids=location_ids,direction_ids=direction_ids,device_ids=device_ids,source_id=source_id,check_items=check_items)
                self.tasks.append(task)
                self.tasks_add.add(task_id)
                logging.info('add_____________________________[%d]', len(self.tasks_add))
                return True
            return False
        
    def del_task(self,task_id):
        i = 0
        for task in self.tasks:
            if task.task_id == task_id:
                logging.info('add_____________________________[%d]', task_id)
                del self.tasks[i]
                self.tasks_add.remove(task_id)
                break
            i+=1
